package com.nbcio.cd.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.nbcio.cd.domain.CdPermission;
import com.nbcio.cd.domain.CdFile;
import com.nbcio.cd.domain.CdFolder;
import com.nbcio.cd.domain.vo.CdPermissionVo;
import com.nbcio.cd.mapper.CdPermissionMapper;
import com.nbcio.cd.mapper.CdFileMapper;
import com.nbcio.cd.mapper.CdFolderMapper;
import com.nbcio.cd.service.ICdPermissionService;
import com.nbcio.cd.utils.CdPermissionUtils;
import com.nbcio.common.core.utils.BeanCopyUtils;
import com.nbcio.common.core.utils.StringUtils;
import com.nbcio.common.satoken.utils.LoginHelper;
import com.nbcio.system.domain.vo.SysRoleVo;
import com.nbcio.system.domain.vo.SysUserVo;
import com.nbcio.system.service.ISysRoleService;
import com.nbcio.system.service.ISysUserService;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.stream.Collectors;

import cn.hutool.core.bean.BeanUtil;
import lombok.extern.slf4j.Slf4j;


/**
 * 云网盘权限管理Service业务层处理
 *
 * @author nbacheng
 * @date 2024-01-01
 */
@Slf4j
@Service
public class CdPermissionServiceImpl extends ServiceImpl<CdPermissionMapper, CdPermission> implements ICdPermissionService {

    @Autowired
    private CdFileMapper cdFileMapper;
    
    @Autowired
    private CdFolderMapper cdFolderMapper;
    
    @Autowired
    private ISysUserService sysUserService;
    
    @Autowired
    private ISysRoleService sysRoleService;
    
    // 资源类型常量
    private static final String RESOURCE_TYPE_FILE = "file";
    private static final String RESOURCE_TYPE_FOLDER = "folder";

    @Override
    public List<CdPermissionVo> selectCdPermissionList(CdPermission cdPermission) {
        LambdaQueryWrapper<CdPermission> lqw = new LambdaQueryWrapper<CdPermission>();
        lqw.eq(StringUtils.isNotBlank(cdPermission.getResourceType()), CdPermission::getResourceType, cdPermission.getResourceType());
        lqw.eq(cdPermission.getResourceId() != null, CdPermission::getResourceId, cdPermission.getResourceId());
        lqw.eq(cdPermission.getUserId() != null, CdPermission::getUserId, cdPermission.getUserId());
        lqw.eq(cdPermission.getRoleId() != null, CdPermission::getRoleId, cdPermission.getRoleId());
        lqw.eq(StringUtils.isNotBlank(cdPermission.getPermissionType()), CdPermission::getPermissionType, cdPermission.getPermissionType());
        lqw.eq(StringUtils.isNotBlank(cdPermission.getGrantType()), CdPermission::getGrantType, cdPermission.getGrantType());
        lqw.eq(StringUtils.isNotBlank(cdPermission.getStatus()), CdPermission::getStatus, cdPermission.getStatus());
        lqw.eq(StringUtils.isNotBlank(cdPermission.getTenantId()), CdPermission::getTenantId, cdPermission.getTenantId());
        lqw.orderByDesc(CdPermission::getCreateTime);
        
        List<CdPermission> list = this.list(lqw);
        return BeanCopyUtils.copyList(list, CdPermissionVo.class);
    }

    @Override
    public int insertCdPermission(CdPermission cdPermission) {
        return this.save(cdPermission) ? 1 : 0;
    }

    @Override
    public int updateCdPermission(CdPermission cdPermission) {
        return this.updateById(cdPermission) ? 1 : 0;
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public int deleteCdPermissionByPermissionIds(Long[] permissionIds) {
        int count = 0;
        
        // 删除权限记录之前，先获取权限信息用于级联删除
        for (Long permissionId : permissionIds) {
            CdPermission permission = this.getById(permissionId);
            if (permission != null) {
                // 如果是文件权限，级联删除父文件夹的读取权限
                if ("file".equals(permission.getResourceType()) && "read".equals(permission.getPermissionType())) {
                    CdFile file = cdFileMapper.selectById(permission.getResourceId());
                    if (file != null && file.getFolderId() != null && file.getFolderId() != 0L) {
                        // 检查该文件夹下是否还有其他授权给同一用户/角色的文件（排除当前要删除的权限）
                        boolean hasOtherAuthorizedFiles = checkOtherAuthorizedFilesInFolder(
                            permission.getUserId(), permission.getRoleId(), file.getFolderId(), permission.getResourceId());
                        
                        log.info("检查文件夹下是否还有其他授权文件: folderId={}, hasOtherAuthorizedFiles={}", 
                            file.getFolderId(), hasOtherAuthorizedFiles);
                        
                        // 如果没有其他授权文件，递归删除父文件夹的读取权限
                        if (!hasOtherAuthorizedFiles) {
                            if (permission.getUserId() != null) {
                                log.info("删除文件夹权限 - 用户: userId={}, folderId={}", permission.getUserId(), file.getFolderId());
                                revokeParentFolderPermissions(permission.getUserId(), file.getFolderId());
                            } else if (permission.getRoleId() != null) {
                                log.info("删除文件夹权限 - 角色: roleId={}, folderId={}", permission.getRoleId(), file.getFolderId());
                                revokeParentFolderPermissionsForRole(permission.getRoleId(), file.getFolderId());
                            }
                        }
                    }
                }
                
                count++;
            }
        }
        
        // 删除权限记录
        this.removeByIds(Arrays.asList(permissionIds));
        
        return count;
    }
    
    /**
     * 检查文件夹下是否还有其他被授权的文件
     */
    private boolean checkOtherAuthorizedFilesInFolder(Long userId, Long roleId, Long folderId, Long excludeFileId) {
        LambdaQueryWrapper<CdFile> fileWrapper = new LambdaQueryWrapper<CdFile>();
        fileWrapper.eq(CdFile::getFolderId, folderId);
        fileWrapper.eq(CdFile::getDelFlag, "0");
        List<CdFile> filesInFolder = cdFileMapper.selectList(fileWrapper);
        
        for (CdFile file : filesInFolder) {
            // 排除当前要删除权限的文件
            if (excludeFileId != null && file.getFileId().equals(excludeFileId)) {
                continue;
            }
            
            LambdaQueryWrapper<CdPermission> checkWrapper = new LambdaQueryWrapper<CdPermission>();
            checkWrapper.eq(CdPermission::getResourceType, "file");
            checkWrapper.eq(CdPermission::getResourceId, file.getFileId());
            checkWrapper.eq(CdPermission::getPermissionType, "read");
            checkWrapper.eq(CdPermission::getStatus, "0");
            checkWrapper.eq(CdPermission::getDelFlag, "0");
            
            if (userId != null) {
                checkWrapper.eq(CdPermission::getUserId, userId);
                checkWrapper.eq(CdPermission::getGrantType, "user");
            } else if (roleId != null) {
                checkWrapper.eq(CdPermission::getRoleId, roleId);
                checkWrapper.eq(CdPermission::getGrantType, "role");
            }
            
            if (this.count(checkWrapper) > 0) {
                return true;
            }
        }
        
        return false;
    }

    @Override
    public int deleteCdPermissionByPermissionId(Long permissionId) {
        return this.removeById(permissionId) ? 1 : 0;
    }

    @Override
    public boolean checkUserPermission(Long userId, String resourceType, Long resourceId, String permissionType) {
        // 首先检查基于所有权的权限
        if (checkOwnershipPermission(userId, resourceType, resourceId)) {
            return true;
        }
        
        // 然后检查基于权限表的权限
        LambdaQueryWrapper<CdPermission> lqw = new LambdaQueryWrapper<CdPermission>();
        lqw.eq(CdPermission::getUserId, userId);
        lqw.eq(CdPermission::getResourceType, resourceType);
        lqw.eq(CdPermission::getResourceId, resourceId);
        lqw.eq(CdPermission::getPermissionType, permissionType);
        lqw.eq(CdPermission::getGrantType, "user");
        lqw.eq(CdPermission::getStatus, "0");
        lqw.eq(CdPermission::getDelFlag, "0");
        
        return this.count(lqw) > 0;
    }
    
    /**
     * 检查基于所有权的权限
     */
    private boolean checkOwnershipPermission(Long userId, String resourceType, Long resourceId) {
        if (RESOURCE_TYPE_FILE.equals(resourceType)) {
            // 检查文件所有权 - 使用createBy字段
            LambdaQueryWrapper<CdFile> fileWrapper = new LambdaQueryWrapper<CdFile>();
            fileWrapper.eq(CdFile::getFileId, resourceId);
            fileWrapper.eq(CdFile::getCreateBy, userId);
            fileWrapper.eq(CdFile::getDelFlag, "0");
            return cdFileMapper.selectCount(fileWrapper) > 0;
        } else if (RESOURCE_TYPE_FOLDER.equals(resourceType)) {
            // 检查文件夹所有权 - 使用ownerId字段
            LambdaQueryWrapper<CdFolder> folderWrapper = new LambdaQueryWrapper<CdFolder>();
            folderWrapper.eq(CdFolder::getFolderId, resourceId);
            folderWrapper.eq(CdFolder::getOwnerId, userId);
            folderWrapper.eq(CdFolder::getDelFlag, "0");
            return cdFolderMapper.selectCount(folderWrapper) > 0;
        }
        return false;
    }

    @Override
    public boolean checkRolePermission(Long roleId, String resourceType, Long resourceId, String permissionType) {
        LambdaQueryWrapper<CdPermission> lqw = new LambdaQueryWrapper<CdPermission>();
        lqw.eq(CdPermission::getRoleId, roleId);
        lqw.eq(CdPermission::getResourceType, resourceType);
        lqw.eq(CdPermission::getResourceId, resourceId);
        lqw.eq(CdPermission::getPermissionType, permissionType);
        lqw.eq(CdPermission::getGrantType, "role");
        lqw.eq(CdPermission::getStatus, "0");
        lqw.eq(CdPermission::getDelFlag, "0");
        
        return this.count(lqw) > 0;
    }

    @Override
    public List<String> getUserPermissions(Long userId, String resourceType, Long resourceId) {
        LambdaQueryWrapper<CdPermission> lqw = new LambdaQueryWrapper<CdPermission>();
        lqw.eq(CdPermission::getUserId, userId);
        lqw.eq(CdPermission::getResourceType, resourceType);
        lqw.eq(CdPermission::getResourceId, resourceId);
        lqw.eq(CdPermission::getGrantType, "user");
        lqw.eq(CdPermission::getStatus, "0");
        lqw.eq(CdPermission::getDelFlag, "0");
        
        List<CdPermission> permissions = this.list(lqw);
        return permissions.stream()
                .map(CdPermission::getPermissionType)
                .collect(Collectors.toList());
    }

    @Override
    public List<String> getRolePermissions(Long roleId, String resourceType, Long resourceId) {
        LambdaQueryWrapper<CdPermission> lqw = new LambdaQueryWrapper<CdPermission>();
        lqw.eq(CdPermission::getRoleId, roleId);
        lqw.eq(CdPermission::getResourceType, resourceType);
        lqw.eq(CdPermission::getResourceId, resourceId);
        lqw.eq(CdPermission::getGrantType, "role");
        lqw.eq(CdPermission::getStatus, "0");
        lqw.eq(CdPermission::getDelFlag, "0");
        
        List<CdPermission> permissions = this.list(lqw);
        return permissions.stream()
                .map(CdPermission::getPermissionType)
                .collect(Collectors.toList());
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public int grantUserPermission(Long userId, String resourceType, Long resourceId, List<String> permissionTypes) {
        int count = 0;
        Long currentUserId = LoginHelper.getUserId();
        
        for (String permissionType : permissionTypes) {
            // 检查是否已存在
            LambdaQueryWrapper<CdPermission> lqw = new LambdaQueryWrapper<CdPermission>();
            lqw.eq(CdPermission::getUserId, userId);
            lqw.eq(CdPermission::getResourceType, resourceType);
            lqw.eq(CdPermission::getResourceId, resourceId);
            lqw.eq(CdPermission::getPermissionType, permissionType);
            lqw.eq(CdPermission::getGrantType, "user");
            
            CdPermission existingPermission = this.getOne(lqw);
            
            if (existingPermission != null) {
                // 更新现有权限
                existingPermission.setStatus("0");
                existingPermission.setUpdateBy(currentUserId);
                this.updateById(existingPermission);
            } else {
                // 创建新权限
                CdPermission permission = new CdPermission();
                permission.setResourceType(resourceType);
                permission.setResourceId(resourceId);
                permission.setUserId(userId);
                permission.setPermissionType(permissionType);
                permission.setGrantType("user");
                permission.setStatus("0");
                permission.setCreateBy(currentUserId);
                permission.setUpdateBy(currentUserId);
                
                this.save(permission);
            }
            count++;
        }
        
        // 如果是文件权限，级联授权给父文件夹
        if ("file".equals(resourceType) && cdFileMapper != null) {
            CdFile file = cdFileMapper.selectById(resourceId);
            if (file != null && file.getFolderId() != null && file.getFolderId() != 0L) {
                // 递归授权所有父文件夹的读取权限
                grantParentFolderPermissions(userId, file.getFolderId(), currentUserId);
            }
        }
        
        return count;
    }
    
    /**
     * 递归授权父文件夹的读取权限
     */
    private void grantParentFolderPermissions(Long userId, Long folderId, Long currentUserId) {
        if (folderId == null || folderId == 0L) {
            return;
        }
        
        CdFolder folder = cdFolderMapper.selectById(folderId);
        if (folder == null) {
            return;
        }
        
        // 检查是否已有读取权限
        LambdaQueryWrapper<CdPermission> lqw = new LambdaQueryWrapper<CdPermission>();
        lqw.eq(CdPermission::getUserId, userId);
        lqw.eq(CdPermission::getResourceType, "folder");
        lqw.eq(CdPermission::getResourceId, folderId);
        lqw.eq(CdPermission::getPermissionType, "read");
        lqw.eq(CdPermission::getGrantType, "user");
        
        CdPermission existingPermission = this.getOne(lqw);
        
        if (existingPermission == null) {
            // 创建文件夹读取权限
            CdPermission permission = new CdPermission();
            permission.setResourceType("folder");
            permission.setResourceId(folderId);
            permission.setUserId(userId);
            permission.setPermissionType("read");
            permission.setGrantType("user");
            permission.setStatus("0");
            permission.setCreateBy(currentUserId);
            permission.setUpdateBy(currentUserId);
            this.save(permission);
        }
        
        // 递归处理父文件夹
        if (folder.getParentId() != null && folder.getParentId() != 0L) {
            grantParentFolderPermissions(userId, folder.getParentId(), currentUserId);
        }
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public int grantRolePermission(Long roleId, String resourceType, Long resourceId, List<String> permissionTypes) {
        int count = 0;
        Long currentUserId = LoginHelper.getUserId();
        
        for (String permissionType : permissionTypes) {
            // 检查是否已存在
            LambdaQueryWrapper<CdPermission> lqw = new LambdaQueryWrapper<CdPermission>();
            lqw.eq(CdPermission::getRoleId, roleId);
            lqw.eq(CdPermission::getResourceType, resourceType);
            lqw.eq(CdPermission::getResourceId, resourceId);
            lqw.eq(CdPermission::getPermissionType, permissionType);
            lqw.eq(CdPermission::getGrantType, "role");
            
            CdPermission existingPermission = this.getOne(lqw);
            
            if (existingPermission != null) {
                // 更新现有权限
                existingPermission.setStatus("0");
                existingPermission.setUpdateBy(currentUserId);
                this.updateById(existingPermission);
            } else {
                // 创建新权限
                CdPermission permission = new CdPermission();
                permission.setResourceType(resourceType);
                permission.setResourceId(resourceId);
                permission.setRoleId(roleId);
                permission.setPermissionType(permissionType);
                permission.setGrantType("role");
                permission.setStatus("0");
                permission.setCreateBy(currentUserId);
                permission.setUpdateBy(currentUserId);
                
                this.save(permission);
            }
            count++;
        }
        
        // 如果是文件权限，级联授权给父文件夹
        if ("file".equals(resourceType) && cdFileMapper != null) {
            CdFile file = cdFileMapper.selectById(resourceId);
            if (file != null && file.getFolderId() != null && file.getFolderId() != 0L) {
                // 递归授权所有父文件夹的读取权限（角色权限）
                grantParentFolderPermissionsForRole(roleId, file.getFolderId(), currentUserId);
            }
        }
        
        return count;
    }
    
    /**
     * 递归授权父文件夹的读取权限（角色权限）
     */
    private void grantParentFolderPermissionsForRole(Long roleId, Long folderId, Long currentUserId) {
        if (folderId == null || folderId == 0L) {
            return;
        }
        
        CdFolder folder = cdFolderMapper.selectById(folderId);
        if (folder == null) {
            return;
        }
        
        // 检查是否已有读取权限
        LambdaQueryWrapper<CdPermission> lqw = new LambdaQueryWrapper<CdPermission>();
        lqw.eq(CdPermission::getRoleId, roleId);
        lqw.eq(CdPermission::getResourceType, "folder");
        lqw.eq(CdPermission::getResourceId, folderId);
        lqw.eq(CdPermission::getPermissionType, "read");
        lqw.eq(CdPermission::getGrantType, "role");
        
        CdPermission existingPermission = this.getOne(lqw);
        
        if (existingPermission == null) {
            // 创建文件夹读取权限
            CdPermission permission = new CdPermission();
            permission.setResourceType("folder");
            permission.setResourceId(folderId);
            permission.setRoleId(roleId);
            permission.setPermissionType("read");
            permission.setGrantType("role");
            permission.setStatus("0");
            permission.setCreateBy(currentUserId);
            permission.setUpdateBy(currentUserId);
            this.save(permission);
        }
        
        // 递归处理父文件夹
        if (folder.getParentId() != null && folder.getParentId() != 0L) {
            grantParentFolderPermissionsForRole(roleId, folder.getParentId(), currentUserId);
        }
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public int revokeUserPermission(Long userId, String resourceType, Long resourceId, List<String> permissionTypes) {
        LambdaQueryWrapper<CdPermission> lqw = new LambdaQueryWrapper<CdPermission>();
        lqw.eq(CdPermission::getUserId, userId);
        lqw.eq(CdPermission::getResourceType, resourceType);
        lqw.eq(CdPermission::getResourceId, resourceId);
        lqw.in(CdPermission::getPermissionType, permissionTypes);
        lqw.eq(CdPermission::getGrantType, "user");
        
        int deletedCount = this.remove(lqw) ? permissionTypes.size() : 0;
        
        // 如果是文件权限，级联删除父文件夹的读取权限
        if ("file".equals(resourceType) && deletedCount > 0 && cdFileMapper != null) {
            CdFile file = cdFileMapper.selectById(resourceId);
            if (file != null && file.getFolderId() != null && file.getFolderId() != 0L) {
                // 递归删除父文件夹的读取权限
                revokeParentFolderPermissions(userId, file.getFolderId());
            }
        }
        
        return deletedCount;
    }
    
    /**
     * 递归撤销父文件夹的读取权限
     */
    private void revokeParentFolderPermissions(Long userId, Long folderId) {
        if (folderId == null || folderId == 0L) {
            return;
        }
        
        // 检查该文件夹是否有其他被授权的文件
        CdFolder folder = cdFolderMapper.selectById(folderId);
        if (folder == null) {
            return;
        }
        
        // 检查该文件夹下是否还有其他授权给用户的文件
        boolean hasOtherAuthorizedFiles = false;
        LambdaQueryWrapper<CdFile> fileWrapper = new LambdaQueryWrapper<CdFile>();
        fileWrapper.eq(CdFile::getFolderId, folderId);
        fileWrapper.eq(CdFile::getDelFlag, "0");
        List<CdFile> filesInFolder = cdFileMapper.selectList(fileWrapper);
        
        for (CdFile file : filesInFolder) {
            LambdaQueryWrapper<CdPermission> checkWrapper = new LambdaQueryWrapper<CdPermission>();
            checkWrapper.eq(CdPermission::getUserId, userId);
            checkWrapper.eq(CdPermission::getResourceType, "file");
            checkWrapper.eq(CdPermission::getResourceId, file.getFileId());
            checkWrapper.eq(CdPermission::getPermissionType, "read");
            checkWrapper.eq(CdPermission::getGrantType, "user");
            checkWrapper.eq(CdPermission::getStatus, "0");
            checkWrapper.eq(CdPermission::getDelFlag, "0");
            
            if (this.count(checkWrapper) > 0) {
                hasOtherAuthorizedFiles = true;
                break;
            }
        }
        
        // 如果该文件夹下没有其他授权文件，删除文件夹权限
        if (!hasOtherAuthorizedFiles) {
            LambdaQueryWrapper<CdPermission> permissionWrapper = new LambdaQueryWrapper<CdPermission>();
            permissionWrapper.eq(CdPermission::getUserId, userId);
            permissionWrapper.eq(CdPermission::getResourceType, "folder");
            permissionWrapper.eq(CdPermission::getResourceId, folderId);
            permissionWrapper.eq(CdPermission::getPermissionType, "read");
            permissionWrapper.eq(CdPermission::getGrantType, "user");
            this.remove(permissionWrapper);
            
            log.info("删除文件夹权限: folderId={}, userId={}", folderId, userId);
        }
        
        // 递归处理父文件夹
        if (folder.getParentId() != null && folder.getParentId() != 0L) {
            revokeParentFolderPermissions(userId, folder.getParentId());
        }
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public int revokeRolePermission(Long roleId, String resourceType, Long resourceId, List<String> permissionTypes) {
        LambdaQueryWrapper<CdPermission> lqw = new LambdaQueryWrapper<CdPermission>();
        lqw.eq(CdPermission::getRoleId, roleId);
        lqw.eq(CdPermission::getResourceType, resourceType);
        lqw.eq(CdPermission::getResourceId, resourceId);
        lqw.in(CdPermission::getPermissionType, permissionTypes);
        lqw.eq(CdPermission::getGrantType, "role");
        
        int deletedCount = this.remove(lqw) ? permissionTypes.size() : 0;
        
        // 如果是文件权限，级联删除父文件夹的读取权限
        if ("file".equals(resourceType) && deletedCount > 0 && cdFileMapper != null) {
            CdFile file = cdFileMapper.selectById(resourceId);
            if (file != null && file.getFolderId() != null && file.getFolderId() != 0L) {
                // 递归删除父文件夹的读取权限（角色权限）
                revokeParentFolderPermissionsForRole(roleId, file.getFolderId());
            }
        }
        
        return deletedCount;
    }
    
    /**
     * 递归撤销父文件夹的读取权限（角色权限）
     */
    private void revokeParentFolderPermissionsForRole(Long roleId, Long folderId) {
        if (folderId == null || folderId == 0L) {
            return;
        }
        
        // 检查该文件夹是否有其他被授权的文件
        CdFolder folder = cdFolderMapper.selectById(folderId);
        if (folder == null) {
            return;
        }
        
        // 检查该文件夹下是否还有其他授权给角色的文件
        boolean hasOtherAuthorizedFiles = false;
        LambdaQueryWrapper<CdFile> fileWrapper = new LambdaQueryWrapper<CdFile>();
        fileWrapper.eq(CdFile::getFolderId, folderId);
        fileWrapper.eq(CdFile::getDelFlag, "0");
        List<CdFile> filesInFolder = cdFileMapper.selectList(fileWrapper);
        
        for (CdFile file : filesInFolder) {
            LambdaQueryWrapper<CdPermission> checkWrapper = new LambdaQueryWrapper<CdPermission>();
            checkWrapper.eq(CdPermission::getRoleId, roleId);
            checkWrapper.eq(CdPermission::getResourceType, "file");
            checkWrapper.eq(CdPermission::getResourceId, file.getFileId());
            checkWrapper.eq(CdPermission::getPermissionType, "read");
            checkWrapper.eq(CdPermission::getGrantType, "role");
            checkWrapper.eq(CdPermission::getStatus, "0");
            checkWrapper.eq(CdPermission::getDelFlag, "0");
            
            if (this.count(checkWrapper) > 0) {
                hasOtherAuthorizedFiles = true;
                break;
            }
        }
        
        // 如果该文件夹下没有其他授权文件，删除文件夹权限
        if (!hasOtherAuthorizedFiles) {
            LambdaQueryWrapper<CdPermission> permissionWrapper = new LambdaQueryWrapper<CdPermission>();
            permissionWrapper.eq(CdPermission::getRoleId, roleId);
            permissionWrapper.eq(CdPermission::getResourceType, "folder");
            permissionWrapper.eq(CdPermission::getResourceId, folderId);
            permissionWrapper.eq(CdPermission::getPermissionType, "read");
            permissionWrapper.eq(CdPermission::getGrantType, "role");
            this.remove(permissionWrapper);
            
            log.info("删除文件夹权限（角色）: folderId={}, roleId={}", folderId, roleId);
        }
        
        // 递归处理父文件夹
        if (folder.getParentId() != null && folder.getParentId() != 0L) {
            revokeParentFolderPermissionsForRole(roleId, folder.getParentId());
        }
    }

    @Override
    public List<CdPermissionVo> getResourcePermissions(String resourceType, Long resourceId) {
        LambdaQueryWrapper<CdPermission> lqw = new LambdaQueryWrapper<CdPermission>();
        lqw.eq(CdPermission::getResourceType, resourceType);
        lqw.eq(CdPermission::getResourceId, resourceId);
        lqw.eq(CdPermission::getStatus, "0");
        lqw.eq(CdPermission::getDelFlag, "0");
        lqw.orderByDesc(CdPermission::getCreateTime);
        
        List<CdPermission> list = this.list(lqw);
        
        // 转换为VO并填充用户名和角色名
        List<CdPermissionVo> voList = new ArrayList<>();
        for (CdPermission permission : list) {
            CdPermissionVo vo = new CdPermissionVo();
            BeanUtil.copyProperties(permission, vo);
            
            // 如果是用户权限，查询用户名
            if ("user".equals(permission.getGrantType()) && permission.getUserId() != null) {
                try {
                    SysUserVo user = sysUserService.selectUserById(permission.getUserId());
                    if (user != null) {
                        vo.setUserName(user.getUserName());
                    } else {
                        vo.setUserName("未知用户");
                    }
                } catch (Exception e) {
                    log.warn("获取用户信息失败: userId={}, error={}", permission.getUserId(), e.getMessage());
                    vo.setUserName("未知用户");
                }
            }
            
            // 如果是角色权限，查询角色名
            if ("role".equals(permission.getGrantType()) && permission.getRoleId() != null) {
                try {
                    SysRoleVo role = sysRoleService.selectRoleById(permission.getRoleId());
                    if (role != null) {
                        vo.setRoleName(role.getRoleName());
                    } else {
                        vo.setRoleName("未知角色");
                    }
                } catch (Exception e) {
                    log.warn("获取角色信息失败: roleId={}, error={}", permission.getRoleId(), e.getMessage());
                    vo.setRoleName("未知角色");
                }
            }
            
            voList.add(vo);
        }
        
        return voList;
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public int copyPermissions(String sourceResourceType, Long sourceResourceId, 
                               String targetResourceType, Long targetResourceId) {
        // 获取源资源的所有权限
        LambdaQueryWrapper<CdPermission> lqw = new LambdaQueryWrapper<CdPermission>();
        lqw.eq(CdPermission::getResourceType, sourceResourceType);
        lqw.eq(CdPermission::getResourceId, sourceResourceId);
        lqw.eq(CdPermission::getStatus, "0");
        lqw.eq(CdPermission::getDelFlag, "0");
        
        List<CdPermission> sourcePermissions = this.list(lqw);
        
        int count = 0;
        Long currentUserId = LoginHelper.getUserId();
        
        for (CdPermission sourcePermission : sourcePermissions) {
            CdPermission targetPermission = new CdPermission();
            targetPermission.setResourceType(targetResourceType);
            targetPermission.setResourceId(targetResourceId);
            targetPermission.setUserId(sourcePermission.getUserId());
            targetPermission.setRoleId(sourcePermission.getRoleId());
            targetPermission.setPermissionType(sourcePermission.getPermissionType());
            targetPermission.setGrantType(sourcePermission.getGrantType());
            targetPermission.setStatus("0");
            targetPermission.setCreateBy(currentUserId);
            targetPermission.setUpdateBy(currentUserId);
            
            this.save(targetPermission);
            count++;
        }
        
        return count;
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public int cleanInvalidPermissions() {
        // 清理软删除的权限
        LambdaQueryWrapper<CdPermission> lqw = new LambdaQueryWrapper<CdPermission>();
        lqw.eq(CdPermission::getDelFlag, "2");
        
        List<CdPermission> invalidPermissions = this.list(lqw);
        int count = invalidPermissions.size();
        
        if (count > 0) {
            this.removeByIds(invalidPermissions.stream()
                    .map(CdPermission::getPermissionId)
                    .collect(Collectors.toList()));
        }
        
        return count;
    }
}
